/*
 * @(#)ServerToAgentComm.java
 *
 *
 *
 * ver 1.0 Sep 12, 2007 ggranum
 */
package org.testfire.realm.control.agent;

import java.io.IOException;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.log4j.Logger;
import org.testfire.realm.model.entities.testfire.AgentEntity;
import org.testfire.realm.model.entities.testfire.TestsetEntity;
import org.testfire.realm.model.entities.testfire.TestsetResultEntity;

public class ServerToAgentComm
{
    private ServerToAgentComm()
    {
    }

    /**
     * Pings, but oes not merge the stored values on the agent.
     *
     * @param agent The agent to ping.
     * @return The round trip time for a post to the given agent, or -1 if the agent returned anything other than
     *         a response of '2xx, SUCCESSFUL' (any 200 level response).
     */
    public static int pingAgent( AgentEntity agent )
    {
        Logger log = Logger.getLogger( ServerToAgentComm.class );
        log.info( "Attempting to ping agent '" + agent.getName() + "' at host '" + agent.getHost() + "/action.ping'" );
        String agentRequestPath = agent.getHost() + "/action.ping";
        PostMethod post = new PostMethod( agentRequestPath );
        HttpClient httpclient = new HttpClient();
        long delta = -1;
        try
        {
            long startTime = System.currentTimeMillis();
            int result = httpclient.executeMethod( post );
            long endTime = System.currentTimeMillis();
            if ( 200 <= result && result < 300 )
            {
                delta = endTime - startTime;
            }
            log.info( "Retrieved POST response code " + result + " in " + delta + " millis." );
        }
        catch ( IOException e )
        {
            log.error( "Ping attempt failed.", e );
        }
        finally
        {
            // Release current connection to the connection pool once you are done
            post.releaseConnection();
        }
        return (int)delta;
    }

    public static boolean sendTestsetToAgent( AgentEntity agent, TestsetEntity testset,
        TestsetResultEntity resultEntity )
    {

        Logger log = Logger.getLogger( ServerToAgentComm.class );
        log.info( "Attempting to send testset "
            + testset.getId() + ":" + testset.getName() + " to agent '" + agent.getName()
            + "' at host '" + agent.getHost() + "/testset.run'" );
        String agentRequestPath = agent.getHost() + "/testset.run";
        PostMethod post = new PostMethod( agentRequestPath );
        String testsetStr = testset.getTestsetdata();
        post.addParameter( "testset_javacode", testsetStr );
        post.addParameter( "testset_name", testset.getName() );
        post.addParameter( "testset_id", String.valueOf( testset.getId() ) );
        post.addParameter( "testsetResult_id", String.valueOf( resultEntity.getId() ) );
        HttpClient httpclient = new HttpClient();
        long delta = -1;
        try
        {
            long startTime = System.currentTimeMillis();
            int result = httpclient.executeMethod( post );
            long endTime = System.currentTimeMillis();
            delta = endTime - startTime;
            log.info( "Retrieved POST response code " + result + " in " + delta + " millis." );
            String body = post.getResponseBodyAsString();
            log.info( "Post response: " + body );
            if ( result == HttpStatus.SC_OK )
            {
                Header h = post.getResponseHeader( "response" );

                if ( h != null && h.getValue().equals( "0" ) )
                {

                    log.info( "Agent has accepted testset " + testset.getId() );
                    return true;
                }
                else
                {
                    log.error( "Server returned response code " + h.getValue() );
                    return false;
                }

            }
            else
            {
                log.error( "Agent Says: Response not OK" );
                String str;
                Header httpclientgrrr = post.getResponseHeader( "error_message" );
                if ( httpclientgrrr != null )
                {
                    log.error( httpclientgrrr.getValue() );
                }
                httpclientgrrr = post.getResponseHeader( "error_trace" );
                if ( httpclientgrrr != null )
                {
                    log.error( httpclientgrrr.getValue() );
                }
            }

        }
        catch ( IOException
            e )
        {
            log.error( "Error sending TestsetEntity to agent " + agent.getId() + ":" + agent.getHost() + ".", e );
            return false;
        }
        finally
        {
            // Release current connection to the connection pool once you are done
            post.releaseConnection();
        }
        return false;
    }
}

// eof: ServerToAgentComm.java